package com.personal.dataanalyse.reportmanage.entity;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.personal.core.data.DataColumn;
import com.personal.core.data.DataTable;
import com.personal.core.utils.Assert;
import com.personal.core.utils.CoreUtil;
import com.personal.dataanalyse.consts.FieldConsts;
import com.personal.dataanalyse.enums.AdditionalTypeEnum;
import com.personal.dataanalyse.enums.FieldDataTypeEnum;
import com.personal.dataconvert.ExportData2Html;
import com.personal.dataconvert.bean.CombineColumnConfig;
import com.personal.dataconvert.port.Data2Html;
import com.personal.dataconvert.util.ExcelHtmlUtil;

/**
 * DataColumn报表装饰
 * @author cuibo
 *
 */
public class DataColumnReportEx extends DataColumn
{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    /** 列类型 */
    private String fieldType;
    
    /** 列名称 */
    private String fieldName;
    
    /** 列单位 */
    private String fieldUnit;
    
    /** 条件 */
    private List<ConditionInfo> conditions;
    
    /** 字段数据：用于汇总计算时使用 */
    private String fieldDataSql;
    
    /** 字段数据：用于汇总计算时使用 */
    private String newDataSql;
    
    /** 是否是表达式 */
    private boolean expType;
    
    /** 合计类型 */
    private String totalType;
    
    /** 计算方式 */
    private String calculateType;
    
    /** cb2018 02 24 为了兼容一张表中既有普通参数，又有指标参数 */
    private String targetType;
    
    /** 是另外一个维度的名称列或者是新增的指标名列 */
    private boolean otherGroupCol = false;
    
    /** 该列对应的表头配置 */
    private ReportHeader headerConfig;
    
    /** 列号*/
    private int colNum;
    
    /** 排序 */
    private long showOrder;
    
    /** 附加列类型 */
    private AdditionalTypeEnum additionalType;
    
    /** 列样式 */
    private String styleClass;
    
    /** 是否匹配上了数据（用于移除为匹配的列） */
    private boolean matchData = false;
    
    /** 计算列用到的列 */
    private List<DataColumnReportEx> calColumns;
    
    /** 该列转换后对应的行 */
    private DataRowReportEx rowReportEx;
    
    /** 表头是否添加单位 */
    private boolean headerAddUnit = true;
    
    /** 合并配置 */
    private Set<CombineColumnConfig> combineConfigs;
    
    /**
     * 将自身信息转为HeaderConfig信息
     * @return
     */
    public ReportHeader toHeaderConfig()
    {
        ReportHeader result = new ReportHeader(this.getColumnLable(), this.getColumnName(), 1, this.getColumnLable(), getAlign(), getWidth());
        result.setFieldType(this.getFieldType());
        result.setFieldUnit(this.getFieldUnit());
        result.setStyleClass(this.getStyleClass());
        result.setDisplay(this.isDisplay());
        // 附加列添加一个样式
        result.setStyleClass(isAdditionalCol() ? FieldConsts.ADDITIONAL_ROW_COL + "_" + additionalType.toString() : this.getStyleClass());
        result.setHeaderAddUnit(headerAddUnit);
        // 记住当前列的headerconfig
        this.setHeaderConfig(result);
        return result;
    }
    
    public DataColumnReportEx()
    {
        super();
    }

    public DataColumnReportEx(String columnName, String columnLable)
    {
        super(columnName, columnLable);
    }

    public DataColumnReportEx(String columnName)
    {
        super(columnName);
    }

    public List<ConditionInfo> getConditions()
    {
        if (conditions == null)
        {
            conditions = new ArrayList<ConditionInfo>();
        }
        return conditions;
    }

    public void setConditions(List<ConditionInfo> conditions)
    {
        this.conditions = conditions;
    }

    public boolean isExpType()
    {
        return expType;
    }

    public void setExpType(boolean expType)
    {
        this.expType = expType;
    }

    public String getTotalType()
    {
        return totalType;
    }

    public void setTotalType(String totalType)
    {
        this.totalType = totalType;
    }
    
    public String getFieldType()
    {
        return fieldType;
    }

    public void setFieldType(String fieldType)
    {
        this.fieldType = fieldType;
    }
    
    public String getFieldName()
    {
        return fieldName;
    }

    public void setFieldName(String fieldName)
    {
        this.fieldName = fieldName;
    }

    /**
     * 另外一个维度的名称列
     * @return
     */
    public boolean isOtherGroupCol()
    {
        return otherGroupCol;
    }

    /**
     * 另外一个维度的名称列
     * @param otherGroupCol
     */
    public void setOtherGroupCol(boolean otherGroupCol)
    {
        this.otherGroupCol = otherGroupCol;
    }

    /**
     * 该列对应的表头配置
     * @return
     */
    public ReportHeader getHeaderConfig()
    {
        return headerConfig;
    }

    /**
     * 该列对应的表头配置
     * @param headerConfig
     */
    public void setHeaderConfig(ReportHeader headerConfig)
    {
        this.headerConfig = headerConfig;
    }

    /**
     * 字段数据：用于汇总计算时使用:普通列，计算列，列维度指标 公用
     * @return
     */
    public String getFieldDataSql()
    {
        return fieldDataSql;
    }
    
    /**
     * 字段数据：用于汇总计算时使用:普通列，计算列，列维度指标 公用
     * @param fieldDataSql
     */
    public void setFieldDataSql(String fieldDataSql)
    {
        this.fieldDataSql = fieldDataSql;
    }

    public String getCalculateType()
    {
        return calculateType;
    }

    public void setCalculateType(String calculateType)
    {
        this.calculateType = calculateType;
    }

    public String getTargetType()
    {
        return targetType;
    }

    public void setTargetType(String targetType)
    {
        this.targetType = targetType;
    }

    public long getShowOrder()
    {
        return showOrder;
    }

    public void setShowOrder(long showOrder)
    {
        this.showOrder = showOrder;
    }

    public AdditionalTypeEnum getAdditionalType()
    {
        return additionalType;
    }

    public void setAdditionalType(AdditionalTypeEnum additionalType)
    {
        this.additionalType = additionalType;
    }
    
    /**
     * 是否是附加列
     * @return
     */
    public boolean isAdditionalCol()
    {
        return additionalType != null;
    }

    public int getColNum()
    {
        return colNum;
    }

    public void setColNum(int colNum)
    {
        this.colNum = colNum;
    }
    
    public String getStyleClass()
    {
        return styleClass;
    }

    public void setStyleClass(String styleClass)
    {
        this.styleClass = styleClass;
    }

    public boolean isMatchData()
    {
        return matchData;
    }

    public void setMatchData(boolean matchData)
    {
        this.matchData = matchData;
    }

    public String getFieldUnit()
    {
        return fieldUnit;
    }

    public void setFieldUnit(String fieldUnit)
    {
        this.fieldUnit = fieldUnit;
    }

    public List<DataColumnReportEx> getCalColumns()
    {
        if (calColumns == null)
        {
            calColumns = new ArrayList<DataColumnReportEx>();
        }
        return calColumns;
    }

    public void setCalColumns(List<DataColumnReportEx> calColumns)
    {
        this.calColumns = calColumns;
    }

    /**
     * 将自身信息转成DataRowReportEx
     * @param maxRowGroupDeep  行维度的最大深度
     * @param table 已经填充好列信息的DataTable
     * @return
     * @throws Exception 
     */
    public DataRowReportEx toDataRowReportEx(int maxRowGroupDeep, DataTable table, int rowNum) throws Exception
    {
        DataRowReportEx result = new DataRowReportEx();
        result.setRowNum(rowNum);
        result.initItemMap(table);

        result.setFieldName(this.getFieldName());
        result.setFieldUnit(this.getFieldUnit());
        result.setAlign(this.getAlign());
        result.setConditions(this.getConditions());
        result.setDisplay(this.isDisplay());
        result.setDotNum(this.getDotNum());
        result.setExpType(this.isExpType());
        result.setDataType(this.getDataType());
        result.setFieldDataSql(this.getFieldDataSql());
        result.setNewDataSql(this.getNewDataSql());
        result.setFieldType(this.getFieldType());
        result.setFieldUnit(this.getFieldUnit());
        result.setTotalType(this.getTotalType());
        result.setCalculateType(this.getCalculateType());
        result.setTargetType(this.getTargetType());
        result.setWidth(this.getWidth());
        result.setMatchData(this.isMatchData());
        result.setColumnReportEx(this);
        // 附加行需要加一个样式
        result.getItemMap().put(Data2Html.TRCLASS, isAdditionalCol() ? FieldConsts.ADDITIONAL_ROW_COL + "_" + additionalType.toString() : "");
        
        this.setRowReportEx(result);
        
        // 通过表头分隔符分割
        String columnLabel = this.getColumnLable();
        String[] arr = CoreUtil.split(columnLabel, ExcelHtmlUtil.REPLACEPOINTFLAG, maxRowGroupDeep);
        Assert.isNotNullOrEmpty(arr, "表头信息不合法，转换成表行信息失败！");
        for (int i = 0; i < arr.length; i++)
        {
            result.setValue(table.getColumns().get(i), arr[i]);
            // 设置样式
            result.getItemMap().put(table.getColumns().get(i).getColumnName() + ExportData2Html.TDCLASS, FieldConsts.HEAD_CLASS);
        }
        // 如果arr的长度小于maxRowGroupDeep 则用最后一个值填充后面的列
        int singleMaxCount = 0;
        if (arr.length < maxRowGroupDeep)
        {
            for (int i = arr.length; i < maxRowGroupDeep; i++)
            {
                DataColumn column = table.getColumns().get(i);
                if (column.isDisplay())
                {
                    singleMaxCount++;
                }
                result.setValue(column, arr[arr.length - 1]);
                // 设置样式
                result.getItemMap().put(table.getColumns().get(i).getColumnName() + ExportData2Html.TDCLASS, FieldConsts.HEAD_CLASS);
            }
            // 如果存在这种情况，则该行在该列需要横向合并
            if (singleMaxCount > 0)
            {
                DataColumnReportEx columnReportEx = (DataColumnReportEx) table.getColumns().get(arr.length - 1);
                CombineColumnConfig combineConfig = new CombineColumnConfig(columnReportEx.getColumnName(), CombineColumnConfig.横向合并);
                combineConfig.setSingleMaxCount(singleMaxCount);
                // 不允许合并到数据部分
                combineConfig.setCombineCount(maxRowGroupDeep - 1);
                // 设置只允许合并这一行
                combineConfig.setMinRowScope(rowNum);
                combineConfig.setMaxRowScope(rowNum + 1);
                columnReportEx.getCombineConfigs().add(combineConfig);
            }
        }
        return result;
    }

    public DataRowReportEx getRowReportEx()
    {
        return rowReportEx;
    }

    public void setRowReportEx(DataRowReportEx rowReportEx)
    {
        this.rowReportEx = rowReportEx;
    }
    
    public String getNewDataSql()
    {
        return newDataSql;
    }

    public void setNewDataSql(String newDataSql)
    {
        this.newDataSql = newDataSql;
    }

    public boolean isDate()
    {
        return FieldDataTypeEnum.日期.toString().equals(getDataType());
    }

    public boolean isHeaderAddUnit()
    {
        return headerAddUnit;
    }

    public void setHeaderAddUnit(boolean headerAddUnit)
    {
        this.headerAddUnit = headerAddUnit;
    }

    public Set<CombineColumnConfig> getCombineConfigs()
    {
        return combineConfigs;
    }

    public void setCombineConfigs(Set<CombineColumnConfig> combineConfigs)
    {
        this.combineConfigs = combineConfigs;
    }
    
}
